﻿using RuoVea.ExSugar.Option;
using System.Reflection;

namespace RuoVea.ExSugar.Util;

/// <summary>
/// sqlsugar 配置扩展方法
/// </summary>
public class SugarUtil
{
    /// <summary>
    /// 配置连接属性
    /// </summary>
    /// <param name="config"></param>
    /// <param name="dataInfoCacheService"></param>
    public static void SetDbConfig(DbConnectionConfig config, ICacheService dataInfoCacheService)
    {
        var configureExternalServices = new ConfigureExternalServices
        {
            EntityNameService = (type, entity) => // 处理表
            {
                if (config.EnableUnderLine && !entity.DbTableName.Contains('_'))
                    entity.DbTableName = UtilMethods.ToUnderLine(entity.DbTableName); // 驼峰转下划线
            },
            EntityService = (type, column) => // 处理列
            {
                if (new NullabilityInfoContext().Create(type).WriteState is NullabilityState.Nullable)
                    column.IsNullable = true;
                if (config.EnableUnderLine && !column.IsIgnore && !column.DbColumnName.Contains('_'))
                    column.DbColumnName = UtilMethods.ToUnderLine(column.DbColumnName); // 驼峰转下划线

                if (config.DbType == SqlSugar.DbType.Oracle)
                {
                    if (type.PropertyType == typeof(long) || type.PropertyType == typeof(long?))
                        column.DataType = "number(18)";
                    if (type.PropertyType == typeof(bool) || type.PropertyType == typeof(bool?))
                        column.DataType = "number(1)";
                }
            }
        };
        if (dataInfoCacheService != null)
        {
            //缓存服务
            configureExternalServices.DataInfoCacheService = dataInfoCacheService;
        }

        config.ConfigureExternalServices = configureExternalServices;
        config.InitKeyType = InitKeyType.Attribute;
        config.IsAutoCloseConnection = true;
        config.MoreSettings = new ConnMoreSettings
        {
            IsAutoRemoveDataCache = true,
            SqlServerCodeFirstNvarchar = true // 采用Nvarchar
        };
    }

    ///// <summary>
    ///// 初始化数据库
    ///// </summary>
    ///// <param name="db"></param>
    ///// <param name="config"></param>
    ///// <param name="configId"></param>
    //public static void InitDatabase(SqlSugarScope db, DbConnectionConfig config, string configId)
    //{
    //    if (!config.EnableInitDb) return;
    //    SqlSugarScopeProvider dbProvider = default;
    //    if (config.ConfigId == null)
    //        dbProvider = db.GetConnectionScopeWithAttr<SqlSugarScopeProvider>();
    //    else
    //        dbProvider = db.GetConnectionScope(config.ConfigId);

    //    // 创建数据库
    //    if (config.DbType != SqlSugar.DbType.Oracle)
    //        dbProvider.DbMaintenance.CreateDatabase();

    //    // 获取所有实体表-初始化表结构
    //    var entityTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(SugarTable), false));
    //    if (!entityTypes.Any()) return;
    //    foreach (var entityType in entityTypes)
    //    {
    //        var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
    //        if (tAtt != null && tAtt?.configId?.ToString() != config?.ConfigId?.ToString()) continue;
    //        if (tAtt == null && config?.ConfigId?.ToString() != configId) continue;

    //        var splitTable = entityType.GetCustomAttribute<SplitTableAttribute>();
    //        if (splitTable == null)
    //            dbProvider.CodeFirst.InitTables(entityType);
    //        else
    //            dbProvider.CodeFirst.SplitTables().InitTables(entityType);
    //    }

    //    if (!config.EnableInitSeed) return;

    //    // 获取所有种子配置-初始化数据
    //    var seedDataTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
    //        && u.GetInterfaces().Any(i => i.HasImplementedRawGeneric(typeof(SeedDataEntity<>))));
    //    if (!seedDataTypes.Any()) return;
    //    foreach (var seedType in seedDataTypes)
    //    {
    //        var instance = Activator.CreateInstance(seedType);

    //        var hasDataMethod = seedType.GetMethod("HasData");
    //        var seedData = ((IEnumerable)hasDataMethod?.Invoke(instance, null))?.Cast<object>();
    //        if (seedData == null) continue;

    //        var entityType = seedType.GetInterfaces().First().GetGenericArguments().First();
    //        var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
    //        if (tAtt != null && tAtt.configId.ToString() != config.ConfigId?.ToString()) continue;
    //        if (tAtt == null && config.ConfigId?.ToString() != configId) continue;

    //        var entityInfo = dbProvider.EntityMaintenance.GetEntityInfo(entityType);
    //        if (entityInfo.Columns.Any(u => u.IsPrimarykey))
    //        {
    //            // 按主键进行批量增加和更新
    //            var storage = dbProvider.StorageableByObject(seedData.ToList()).ToStorage();
    //            storage.AsInsertable.ExecuteCommand();
    //            var ignoreUpdate = hasDataMethod.GetCustomAttribute<IgnoreUpdateAttribute>();
    //            if (ignoreUpdate == null)
    //            {
    //                storage.AsUpdateable.ExecuteCommand();
    //            }
    //        }
    //        else
    //        {
    //            // 无主键则只进行插入
    //            if (!dbProvider.Queryable(entityInfo.DbTableName, entityInfo.DbTableName).Any())
    //                dbProvider.InsertableByObject(seedData.ToList()).ExecuteCommand();
    //        }
    //    }
    //}

    ///// <summary>
    ///// 初始化租户业务数据库
    ///// </summary>
    ///// <param name="itenant"></param>
    ///// <param name="config"></param>
    //public static void InitTenantDatabase(ITenant itenant, DbConnectionConfig config)
    //{
    //    SetDbConfig(config, null);

    //    itenant.AddConnection(config);
    //    var db = itenant.GetConnectionScope(config.ConfigId);
    //    db.DbMaintenance.CreateDatabase();

    //    // 获取所有实体表-初始化租户业务表
    //    var entityTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
    //        && u.IsDefined(typeof(SugarTable), false) && !u.IsDefined(typeof(SystemTableAttribute), false));
    //    if (!entityTypes.Any()) return;
    //    foreach (var entityType in entityTypes)
    //    {
    //        var splitTable = entityType.GetCustomAttribute<SplitTableAttribute>();
    //        if (splitTable == null)
    //            db.CodeFirst.InitTables(entityType);
    //        else
    //            db.CodeFirst.SplitTables().InitTables(entityType);
    //    }
    //}

}
